package com.maistars.spider.common.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import org.apache.commons.lang3.StringUtils;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.*;

public class AliyunOssUtil {

    public static String OSS_ADDRESS = "https://luoboask-666.oss-cn-shanghai.aliyuncs.com";

    private static List<String> filters = new ArrayList<>();

    private static List<String> allowTypes = new ArrayList<>();

    static{
        allowTypes = MIMEType.getAllSuffix();
    }

    public static void uploadFile(InputStream fileInputStream, String fileName) {
        String accessKeyId = "bviMuISI6bfn31Xj";
        String accessSecretKey = "IGhdXWieCUEp3p9hu3rCmnNHTbLmiu";

        String endpoint = "oss-cn-shanghai.aliyuncs.com";
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessSecretKey);

        // <yourObjectName>表示上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
        PutObjectRequest putObjectRequest = new PutObjectRequest("luoboask-666", "luobotools"+fileName, fileInputStream);

        // 如果需要上传时设置存储类型与访问权限，请参考以下示例代码。
        // ObjectMetadata metadata = new ObjectMetadata();
        // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
        // metadata.setObjectAcl(CannedAccessControlList.Private);
        // putObjectRequest.setMetadata(metadata);

//        ObjectMetadata metadata = new ObjectMetadata();
//        metadata.setContentLength(fileLength);
//        metadata.setContentType("text/plain");
//        putObjectRequest.setMetadata(metadata);

        ossClient.putObject(putObjectRequest);

//        // 关闭OSSClient。
        ossClient.shutdown();
    }

    public static String uploadFile(InputStream fileInputStream, String prefixPath,String fileName) {
        String accessKeyId = "bviMuISI6bfn31Xj";
        String accessSecretKey = "IGhdXWieCUEp3p9hu3rCmnNHTbLmiu";

        String endpoint = "oss-cn-shanghai.aliyuncs.com";
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessSecretKey);

        // <yourObjectName>表示上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
        PutObjectRequest putObjectRequest = new PutObjectRequest("luoboask-666", prefixPath+"/"+fileName, fileInputStream);

        // 如果需要上传时设置存储类型与访问权限，请参考以下示例代码。
        // ObjectMetadata metadata = new ObjectMetadata();
        // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
        // metadata.setObjectAcl(CannedAccessControlList.Private);
        // putObjectRequest.setMetadata(metadata);

//        ObjectMetadata metadata = new ObjectMetadata();
//        metadata.setContentLength(fileLength);
//        metadata.setContentType("text/plain");
//        putObjectRequest.setMetadata(metadata);

        ossClient.putObject(putObjectRequest);

//        // 关闭OSSClient。
        ossClient.shutdown();

        return putObjectRequest.getKey();
    }

    public static Map<String,String> captureRemoteDataToOss (String urlStr,String groupName) {
        Map<String,String> result = new HashMap<>();
        result.put("status","0");
        HttpURLConnection connection = null;
        URL url = null;

        try {
            url = new URL( urlStr );

            if ( !validHost( url.getHost() ) ) {
                result.put("status","1");
                result.put("msg",url.getHost()+" is illegal");
                return result;
            }

            connection = (HttpURLConnection) url.openConnection();

            connection.setInstanceFollowRedirects( true );
            connection.setUseCaches( true );

            if ( !validContentState( connection.getResponseCode() ) ) {
                result.put("status","1");
                result.put("msg","connection is error");
                return result;
            }

            String suffix = MIMEType.getSuffix( connection.getContentType() );

            if ( !validFileType( suffix ) ) {
                result.put("status","1");
                result.put("msg",suffix+" fileSuffix is illegal");
                return result;
            }

            SimpleDateFormat df = new SimpleDateFormat("yyyy_MM_dd");
            String today = df.format(new Date());
            Random r1 = new Random(10);
            String prefixFilePath = groupName+"/"+today;
            String orignalFileName = StringUtils.substring(urlStr, StringUtils.lastIndexOf(urlStr,"/")+1);
            String encodeOrignalFileName =  new String(orignalFileName.getBytes(), "UTF-8");
            String fileName = r1.nextInt(10000) + "_" + System.currentTimeMillis() + "_" + encodeOrignalFileName;
            String savePath = OSS_ADDRESS +"/"+ prefixFilePath+"/"+fileName;

            if(urlStr.contains(AliyunOssUtil.OSS_ADDRESS)){
                result.put("status","0");
                result.put( "size", "999" );
                result.put( "ossUrl", urlStr );
            }else {
                AliyunOssUtil.uploadFile(connection.getInputStream(), prefixFilePath, fileName);
                result.put("status","0");
                result.put( "size", "999" );
                result.put( "ossUrl", savePath );
            }
            return result;

        } catch ( Exception e ) {
            result.put("status","1");
            result.put("msg","captureRemoteDataToOss occured error");
            return result;
        }
    }

    private static boolean validHost ( String hostname ) {
        try {
            InetAddress ip = InetAddress.getByName(hostname);

            if (ip.isSiteLocalAddress()) {
                return false;
            }
        } catch (UnknownHostException e) {
            return false;
        }

        return !filters.contains( hostname );
    }

    private static boolean validContentState ( int code ) {

        return HttpURLConnection.HTTP_OK == code;

    }

    private static boolean validFileType ( String type ) {

        return allowTypes.contains( type );

    }

}

class MIMEType {

    public static final Map<String, String> types = new HashMap<String, String>(){{
        put( "image/gif", ".gif" );
        put( "image/jpeg", ".jpg" );
        put( "image/jpg", ".jpg" );
        put( "image/png", ".png" );
        put( "image/bmp", ".bmp" );
        put( "image/webp", ".webp" );
    }};

    public static String getSuffix ( String mime ) {
        return MIMEType.types.get( mime );
    }

    public static List<String> getAllSuffix(){
        List<String> allSuffix = new ArrayList<>();
        for(String value:types.values()){
            allSuffix.add(value);
        }
        return allSuffix;
    }

}
